﻿using AutoMapper;
using Common.MyCustomException;
using Common.Result;
using Common.Utils;
using IService;
using Microsoft.AspNetCore.Http;
using Model.Dto.Orders;
using Model.Entitys;
using SqlSugar;
using SqlSugar.DistributedSystem.Snowflake;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class OrderService : IOrderService
    {
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;
        private readonly IShoppingCartService _shoppingCartService;
        private readonly IAddressBookService _addressBookService;
        public OrderService(ISqlSugarClient db, IMapper mapper, 
            IShoppingCartService shoppingCartService, 
            IAddressBookService addressBookService)
        {
            _db = db;
            _mapper = mapper;
            _shoppingCartService = shoppingCartService;
            _addressBookService = addressBookService;
        }

        /// <summary>
        /// 修改订单状态
        /// </summary>
        /// <param name="orderEdit"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task EditOrdersStatusByIdAsync(OrderEdit orderEdit)
        {
            await _db.Updateable(_mapper.Map<Orders>(orderEdit))
                .UpdateColumns(it=>it.Status).ExecuteCommandAsync();
        }

        /// <summary>
        /// 条件分页查询订单
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <param name="number"></param>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PageInfo> GetOrdersAsync(int page, int pageSize, string? number, DateTime? beginTime, DateTime? endTime)
        {
            RefAsync<int> total = 0;
            var OrderList = await _db.Queryable<Orders>()
                .WhereIF(!string.IsNullOrEmpty(number),o => o.Number.Contains(number))
                .WhereIF(beginTime!=null && endTime!=null,o=>o.OrderTime>=beginTime&&o.OrderTime<=endTime)
                .OrderBy(it => it.OrderTime)
                .ToPageListAsync(page, pageSize, total);
            
            return new PageInfo()
            {
                Total = total,
                Data = OrderList
            };
        }

        /// <summary>
        /// 分页查询用户订单
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<PageInfo> GetUserOrdersAsync(int page, int pageSize,long userId)
        {
            RefAsync<int> total = 0;
            var OrderList=await _db.Queryable<Orders>()
                .Where(o => o.UserId == userId)
                .OrderBy(it => it.OrderTime, OrderByType.Desc)
                .ToPageListAsync(page, pageSize, total);
            var OrderResList = _mapper.Map<List<OrderRes>>(OrderList);
            foreach (var orderRes in OrderResList)
            {
                orderRes.OrderDetails = await _db.Queryable<OrderDetail>().Where(o => o.OrderId == orderRes.Id).ToListAsync();
            }
            return new PageInfo()
            {
                Total = total,
                Data = OrderResList
            };
        }

        /// <summary>
        /// 提交订单
        /// </summary>
        /// <param name="orderAdd"></param>
        /// <param name="HttpContext"></param>
        /// <returns></returns>
        /// <exception cref="MyCustomException"></exception>
        public async Task SubmitAsync(OrderAdd orderAdd, HttpContext HttpContext)
        {
            _db.Ado.BeginTran();
            //查询当前用户的购物车数据
            var shoppingCarts =await _shoppingCartService.GetShoppingCartsAsync((long)orderAdd.UserId);
            if (shoppingCarts == null || shoppingCarts.Count == 0)
            {
                throw new MyCustomException("购物车为空，不能下单");
            }
            //查询地址数据
            long addressBookId = (long)orderAdd.AddressBookId;
            var addressBook=await _addressBookService.GetAddressBookByIdAsync(addressBookId);
            if (addressBook == null)
            {
                throw new MyCustomException("用户地址信息有误，不能下单");
            }
            long orderId = SnowflakeIdGenerator.GenerateId();//订单号
            List<OrderDetail> orderDetails = shoppingCarts.Select(item => new OrderDetail
            {
                OrderId= orderId,
                Number=item.Number,
                DishFlavor=item.DishFlavor,
                DishId=item.DishId,
                SetmealId=item.SetmealId,
                Name=item.Name,
                Image=item.Image,
                Amount=item.Amount
            }).ToList();
            decimal amount = shoppingCarts.Sum(item => item.Amount * item.Number);//总价
            var orders =_mapper.Map<Orders>(orderAdd);
            orders.Id = orderId;
            orders.OrderTime = DateTime.Now;
            orders.CheckoutTime = DateTime.Now;
            orders.Status = 2;
            orders.Amount = amount;
            orders.UserId = (long)orderAdd.UserId;
            orders.Number = orderId.ToString();
            orders.UserName = HttpContext.User.Claims.ToList()[1].Value;
            orders.Consignee = addressBook.Consignee;
            orders.Phone = addressBook.Phone;
            //orders.Address = addressBook.ProvinceName == null ? "" : addressBook.ProvinceName
            //    + addressBook.CityName == null ? "" : addressBook.CityName
            //    + addressBook.DistrictName == null ? "" : addressBook.DistrictName
            //    + addressBook.Detail == null ? "" : addressBook.Detail;
            orders.Address = addressBook.Detail;
            //向订单表插入数据，一条数据
            await _db.Insertable(orders).ExecuteCommandAsync();
            //向订单明细表插入数据，多条数据
            await _db.Insertable(orderDetails).ExecuteReturnSnowflakeIdListAsync();

            //清空购物车数据
            await _shoppingCartService.CleanAsync((long)orderAdd.UserId);
            _db.Ado.CommitTran();
        }
    }
}
